﻿using Autofac;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;


namespace Sprout.Core
{
    /**
     * 经测试
     * 如果是AddScoped 模式，通过GetService 获取到的值全局唯一，为单例
     * 同等于AddSingleton 模式
     */
    public class ServiceLocator
    {
        public static ILifetimeScope AutofacContainer { get; set; }
        //是否禁用HttpContainer
        public static bool DisableHttpContainer { set; get; }



        public static bool IsRegistered<T>()
        {
            return AutofacContainer.IsRegistered<T>();
        }

        public static bool IsRegistered<T>(string key)
        {
            return AutofacContainer.IsRegisteredWithKey<T>(key);
        }

        public static bool IsRegistered(Type type)
        {
            return AutofacContainer.IsRegistered(type);
        }

        public static bool IsRegisteredWithKey(string key, Type type)
        {
            return AutofacContainer.IsRegisteredWithKey(key, type);
        }

        /// <summary>
        /// 获取Option
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T GetOption<T>()
             where T : class, new()
        {
            return GetService<IOptions<T>>().Value;
        }


        public static T GetService<T>()
        {

            return AutofacContainer.Resolve<T>();
        }

        public static T GetService<T>(string key)
        {

            return AutofacContainer.ResolveKeyed<T>(key);
        }

        public static object GetService(Type type)
        {
            return AutofacContainer.Resolve(type);
        }

        public static object GetService(string key, Type type)
        {
            return AutofacContainer.ResolveKeyed(key, type);
        }

        /// <summary>
        /// 获取当前生命周期的实例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T GetScopeService<T>() where T : class
        {
            if (!DisableHttpContainer && GetService<IHttpContextAccessor>().HttpContext != null)
            {
                return (T)GetService<IHttpContextAccessor>().HttpContext.RequestServices.GetService(typeof(T));
            }
            return GetService<T>();
        }
        /// <summary>
        /// 获取当前生命周期的实例
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static object GetScopeService(Type type)
        {
            if (!DisableHttpContainer && GetService<IHttpContextAccessor>().HttpContext != null)
            {
                return GetService<IHttpContextAccessor>().HttpContext.RequestServices.GetService(type);
            }
            return GetService(type);
        }




        /// <summary>
        /// 获取实例--懒加载
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static Lazy<T> GetLazyService<T>()
        {
            return new Lazy<T>(() => GetService<T>());
        }
        /// <summary>
        /// 获取实例--懒加载
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static Lazy<T> GetLazyService<T>(string key)
        {
            return new Lazy<T>(() => GetService<T>(key));
        }
        /// <summary>
        /// 获取实例--懒加载
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static Lazy<object> GetLazyService(Type type)
        {
            return new Lazy<object>(() => GetService(type));
        }
        /// <summary>
        /// 获取实例--懒加载
        /// </summary>
        /// <param name="key"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static Lazy<object> GetLazyService(string key, Type type)
        {
            return new Lazy<object>(() => GetService(key, type));
        }
        /// <summary>
        /// 获取当前生命周期的实例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static Lazy<T> GetLazyScopeService<T>() where T : class
        {
            return new Lazy<T>(() => GetScopeService<T>());
        }
        /// <summary>
        /// 获取当前生命周期的实例
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static Lazy<object> GetLazyScopeService(Type type)
        {
            return new Lazy<object>(() => GetScopeService(type));
        }
    }
}
